/*
 * Tranquil Java Integrated Development Environment
 *
 * The GNU General Public License Version 3
 *
 * Copyright (C) 2021 Autumn Lamonte
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * @author Autumn Lamonte [AutumnWalksTheLake@gmail.com] ⚧ Trans Liberation Now
 * @version 1
 */
package tjide.ui;

import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;

import gjexer.TAction;
import gjexer.TApplication;
import gjexer.TButton;
import gjexer.TCheckBox;
import gjexer.TComboBox;
import gjexer.TField;
import gjexer.TWindow;
import gjexer.bits.CellAttributes;

/**
 * This window is used to configure the TJ overall application preferences.
 */
public class ApplicationOptionsWindow extends TWindow {

    /**
     * Translated strings.
     */
    private static ResourceBundle i18n = ResourceBundle.getBundle(ApplicationOptionsWindow.class.getName());

    // ------------------------------------------------------------------------
    // Constants --------------------------------------------------------------
    // ------------------------------------------------------------------------

    // ------------------------------------------------------------------------
    // Variables --------------------------------------------------------------
    // ------------------------------------------------------------------------

    /**
     * Options for using ptypipe.
     */
    private TComboBox ptypipe = null;

    /**
     * Whether or not terminal windows close on exit.
     */
    private TCheckBox closeOnExit = null;

    /**
     * Whether or not to use an external editor.
     */
    private TCheckBox externalEditor = null;

    /**
     * Name of the external editor when editing a new file.
     */
    private TField externalEditorNew = null;

    /**
     * Name of the external editor when opening an existing file.
     */
    private TField externalEditorOpen = null;

    /**
     * Name of the external editor when opening an existing file to a
     * specific line.
     */
    private TField externalEditorOpenToLine = null;

    /**
     * Whether or not to use an external Java compiler.
     */
    private TCheckBox externalJavac = null;

    /**
     * Name of the external Java compiler.
     */
    private TField externalJdkBin = null;

    /**
     * Name of the external Java runtime.
     */
    private TField externalJreBin = null;

    // ------------------------------------------------------------------------
    // Constructors -----------------------------------------------------------
    // ------------------------------------------------------------------------

    /**
     * Public constructor.
     *
     * @param parent the main application
     */
    public ApplicationOptionsWindow(final TApplication parent) {

        super(parent, i18n.getString("windowTitle"), 0, 0, 76, 23,
            MODAL | CENTERED);

        final TranquilApplication app = ((TranquilApplication) getApplication());

        final int buttonOffset = 14;

        // Create a status bar
        statusBar = newStatusBar(i18n.getString("statusBar"));

        // ptypipe option
        addLabel(i18n.getString("usePtypipe"), 3, 2, "tcheckbox.inactive",
            false,
            new TAction() {
                public void DO() {
                    ptypipe.activate();
                }
            });
        List<String> ptypipeOptions = new ArrayList<String>();
        ptypipeOptions.add("auto");
        ptypipeOptions.add("true");
        ptypipeOptions.add("false");
        ptypipe = addComboBox(22, 2, 10, ptypipeOptions, 0, 5,
            new TAction() {
                public void DO() {
                    app.setOption("gjexer.TTerminal.ptypipe",
                        ptypipe.getText());
                }
            });
        ptypipe.setText(app.getOption("gjexer.TTerminal.ptypipe"), false);
        closeOnExit = addCheckBox(3, 3, i18n.getString("closeWindowOnExit"),
            app.getOption("gjexer.TTerminal.closeOnExit").equals("true"));

        // Use external editor
        externalEditor = addCheckBox(3, 7, i18n.getString("useExternalEditor"),
            app.getOption("editor.useExternal").equals("true"));

        // External editor
        addLabel(i18n.getString("externalEditorNew"), 5, 9, "ttext", false);
        externalEditorNew = addField(22, 9, 25, false,
            app.getOption("editor.external.new"));
        addLabel(i18n.getString("externalEditorOpen"), 5, 10, "ttext", false);
        externalEditorOpen = addField(22, 10, 25, false,
            app.getOption("editor.external.open"));
        addLabel(i18n.getString("externalEditorOpenToLine"), 5, 11, "ttext",
            false);
        externalEditorOpenToLine = addField(22, 11, 25, false,
            app.getOption("editor.external.openToLine"));

        // Java compiler and JRE
        externalJavac = addCheckBox(3, 15, i18n.getString("useExternalJava"),
            app.getOption("compiler.java.useExternal").equals("true"));
        addLabel(i18n.getString("externalJdkBin"), 5, 17, "ttext", false);
        externalJdkBin = addField(22, 17, 25, false,
            app.getOption("compiler.java.jdkBin"));
        addLabel(i18n.getString("externalJreBin"), 5, 18, "ttext", false);
        externalJreBin = addField(22, 18, 25, false,
            app.getOption("compiler.java.jreBin"));

        // Buttons
        addButton(i18n.getString("saveButton"), getWidth() - buttonOffset, 4,
            new TAction() {
                public void DO() {
                    // Copy values from window to properties, save and close
                    // window.
                    ApplicationOptionsWindow.this.copyOptions();
                    ApplicationOptionsWindow.this.saveOptions();
                    ApplicationOptionsWindow.this.close();
                }
            });

        addButton(i18n.getString("resetButton"), getWidth() - buttonOffset, 6,
            new TAction() {
                public void DO() {
                    // Reset to defaults, copy values into window.
                    ApplicationOptionsWindow.this.resetOptions();
                    ApplicationOptionsWindow.this.loadOptions();
                }
            });

        addButton(i18n.getString("okButton"), getWidth() - buttonOffset, 8,
            new TAction() {
                public void DO() {
                    // Copy values from window to properties, close window.
                    ApplicationOptionsWindow.this.copyOptions();
                    ApplicationOptionsWindow.this.close();
                }
            });

        TButton cancelButton = addButton(i18n.getString("cancelButton"),
            getWidth() - buttonOffset, 10,
            new TAction() {
                public void DO() {
                    // Don't copy anything, just close the window.
                    ApplicationOptionsWindow.this.close();
                }
            });

        // Save this for last: make the cancel button default action.
        activate(cancelButton);

        // Reset window fields to the application options.
        loadOptions();
    }

    // ------------------------------------------------------------------------
    // Event handlers ---------------------------------------------------------
    // ------------------------------------------------------------------------

    // ------------------------------------------------------------------------
    // TWindow ----------------------------------------------------------------
    // ------------------------------------------------------------------------

    /**
     * Draw the options panel.
     */
    @Override
    public void draw() {
        // Draw window and border.
        super.draw();

        CellAttributes boxColor = getTheme().getColor("ttext");

        // Shells
        drawBox(2, 2, 50, 6, boxColor, boxColor);
        putStringXY(4, 2, i18n.getString("osShellTitle"), boxColor);

        // Editor
        drawBox(2, 7, 50, 14, boxColor, boxColor);
        putStringXY(4, 7, i18n.getString("editorTitle"), boxColor);

        // Java
        drawBox(2, 15, 50, 21, boxColor, boxColor);
        putStringXY(4, 15, i18n.getString("javaTitle"), boxColor);

    }

    // ------------------------------------------------------------------------
    // ApplicationOptionsWindow -----------------------------------------------
    // ------------------------------------------------------------------------

    /**
     * Copy options from window fields to the application properties.
     */
    private void copyOptions() {
        TranquilApplication app = ((TranquilApplication) getApplication());

        // ptypipe
        app.setOption("gjexer.TTerminal.ptypipe", ptypipe.getText());

        // closeOnExit
        if (closeOnExit.isChecked()) {
            app.setOption("gjexer.TTerminal.closeOnExit", "true");
        } else {
            app.setOption("gjexer.TTerminal.closeOnExit", "false");
        }

        // External editor
        if (externalEditor.isChecked()) {
            app.setOption("editor.useExternal", "true");
        } else {
            app.setOption("editor.useExternal", "false");
        }
        app.setOption("editor.external.new", externalEditorNew.getText());
        app.setOption("editor.external.open", externalEditorOpen.getText());
        app.setOption("editor.external.openToLine",
            externalEditorOpenToLine.getText());

        // Java compiler and JRE
        if (externalJavac.isChecked()) {
            app.setOption("compiler.java.useExternal", "true");
        } else {
            app.setOption("compiler.java.useExternal", "false");
        }
        app.setOption("compiler.java.jdkBin", externalJdkBin.getText());
        app.setOption("compiler.java.jreBin", externalJreBin.getText());

        // Make these options effective for the running session.
        app.resolveOptions();
    }

    /**
     * Save application properties.
     */
    private void saveOptions() {
        TranquilApplication app = ((TranquilApplication) getApplication());
        app.saveOptions();
    }

    /**
     * Copy options from the application properties to window fields.
     */
    private void loadOptions() {
        TranquilApplication app = ((TranquilApplication) getApplication());

        // ptypipe
        ptypipe.setText(app.getOption("gjexer.TTerminal.ptypipe"), false);

        // closeOnExit
        closeOnExit.setChecked(app.getOption("gjexer.TTerminal.closeOnExit").
            equals("true"));

        // External editor
        externalEditor.setChecked(app.getOption("editor.useExternal").
            equals("true"));
        externalEditorNew.setText(app.getOption("editor.external.new"));
        externalEditorOpen.setText(app.getOption("editor.external.open"));
        externalEditorOpenToLine.setText(app.getOption(
            "editor.external.openToLine"));

        // Java compiler and JRE
        externalJavac.setChecked(app.getOption("compiler.java.useExternal").
            equals("true"));
        externalJdkBin.setText(app.getOption("compiler.java.jdkBin"));
        externalJreBin.setText(app.getOption("compiler.java.jreBin"));

    }

    /**
     * Reset options from the application.
     */
    private void resetOptions() {
        TranquilApplication app = ((TranquilApplication) getApplication());
        app.setDefaultOptions();
    }

}
